#include <cstdlib>
#include <iostream>
#include <cmath>
#include <cairo/cairo.h>
#include <cairo/cairo-svg.h>

#include "swf.h"
#include "DefineShape3.h"
#include "StyleChangeRecord.h"
using namespace std;

using namespace swfstream;

DefineShape3* DefineShape3::from_file(FILE* f) {
	long s = ftell(f);
	DefineShape3*r = new DefineShape3;
	//fread(&r->shape_id,2,1,f);
	fread(&r->CharacterID, 2, 1, f);
	//printf("define_shape3::shape_id=%u,",(uint)r->shape_id);
	r->shape_bounds = Rect::from_file(f);
	r->shape_bounds->print();
	r->shapes = ShapeWithStyle::from_file(f, 3);
	//puts("define_shape3 read done");
//	r->print();
	//printf("length of define_shape3:%ld\n",ftell(f)-s);
	return r;
}
void DefineShape3::print() {
	Tag::print();
	//cout<<"define_shape3::shapeid:"<<shape_id<<",shapebounds:";
	cout << "define_shape3::shapeid:" << CharacterID << ",shapebounds:";
	shape_bounds->print();
	shapes->print();

}
bool DefineShape3::to_svg(const char* fname) {
	//return false;
	cerr << "fname:" << fname << endl;
	const int n = 20;

	cairo_surface_t *surface;
	cairo_t *cr;
//	surface=cairo_svg_surface_create(fn,1500,1500);
//	surface=cairo_svg_surface_create(fn,shape_bounds->x_max-shape_bounds->x_min,shape_bounds->y_max-shape_bounds->y_min);
	//surface=cairo_svg_surface_create(fname,shape_bounds->x_max,shape_bounds->y_max);
	surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
			shape_bounds->x_max / n, shape_bounds->y_max / n);
	cr = cairo_create(surface);
	cairo_set_source_rgb(cr, 0, 0, 0);
	cairo_set_line_width(cr, 1);
	//cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT);
//	cairo_move_to (cr, 40, 60);
//	cairo_move_to (cr, 60, 60);
//	cairo_line_to (cr, 360, 60);
	//cairo_stroke (cr);
	//return false;

//	cout<<"mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmstart shape\n";
	FillStyle *fill0 = NULL;
	FillStyle *fill1 = NULL;
	LineStyle *line = NULL;
	int x = 0, y = 0;
	for (uint i = 0; i < shapes->ShapeRecords->size(); i++) {
		ShapeRecord* record = shapes->ShapeRecords->at(i);
		if (dynamic_cast<StyleChangeRecord*>(record)) {
			StyleChangeRecord* change = (StyleChangeRecord*) record;
//			cout<<"qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqstart record\n";
			change->print();
			if (change->StateFillStyle1 || change->StateNewStyles) {
				cerr << "to_svg not finished\n";
				exit(1);
			}
			if (change->StateLineStyle) {
				cerr << "LineStyle:::::::" << change->LineStyle;
				//exit(1);
				if (change->LineStyle == 0) {
					line = NULL;
				} else {
					line = shapes->LineStyles->at(change->LineStyle - 1);
				}
			}
			if (change->StateFillStyle0) {
				cerr << "FillStyle0:::::::" << dec << change->FillStyle0;
				//exit(1);
				if (change->FillStyle0 == 0) {
					fill0 = NULL;
				} else {
					fill0 = shapes->FillStyles->at(change->FillStyle0 - 1);
				}
			}
			if (change->StateMoveTo) {
				cout << "movevector:\t" << change->MoveDeltaX << "\t#\t"
						<< change->MoveDeltaY << endl;
				//int x1=x+change->MoveDeltaX;
				//int y1=y+change->MoveDeltaY;
				int x1 = change->MoveDeltaX;
				int y1 = change->MoveDeltaY;
				cairo_move_to(cr, x / n, y / n);
				//cairo_line_to (cr, x1/n, y1/n);
				x = x1;
				y = y1;
				cout << "move to:\t" << x << "\t#\t" << y << endl;
			}
		} else if (dynamic_cast<STRAIGHTEDGERECORD*>(record)) {
			STRAIGHTEDGERECORD* straight = (STRAIGHTEDGERECORD*) record;
			cout << "line vector:\t" << straight->DeltaX << "\t#\t"
					<< straight->DeltaY << endl;
			int x1 = x, y1 = y;
			//if(straight->GeneralLineFlag||!straight->VertLineFlag){
			x1 += straight->DeltaX;
			//if(straight->GeneralLineFlag||straight->VertLineFlag){
			y1 += straight->DeltaY;
			cout << "line to:\t" << x1 << "\t#\t" << y1 << endl;
			cairo_move_to(cr, x / n, y / n);
			cairo_line_to(cr, x1 / n, y1 / n);
			//cairo_stroke (cr);
			x = x1;
			y = y1;
		} else if (dynamic_cast<CURVEDEDGERECORD*>(record)) {
			CURVEDEDGERECORD* straight = (CURVEDEDGERECORD*) record;
			cout << "curve vector:\t"
					<< straight->ControlDeltaX + straight->AnchorDeltaX
					<< "\t#\t"
					<< straight->ControlDeltaY + straight->AnchorDeltaY << endl;
			int x1 = x, y1 = y;
			x1 += (straight->ControlDeltaX + straight->AnchorDeltaX);
			y1 += (straight->ControlDeltaY + straight->AnchorDeltaY);
			cout << "curve to:\t" << x1 << "\t#\t" << y1 << endl;
			cairo_move_to(cr, x / n, y / n);
			cairo_line_to(cr, x1 / n, y1 / n);
			x = x1;
			y = y1;
		} else {
			cerr << "err";
			exit(1);
		}
	}
	cout
			<< "nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn end shape\n";

	/*
	 cairo_arc (cr, x + width - r, y + r, r, 3 * M_PI / 2, 2 * M_PI);
	 cairo_arc (cr, x + width - r, y + height - r, r, 0, M_PI / 2);
	 cairo_arc (cr, x + r, y + height - r, r, M_PI / 2, M_PI);
	 */
	cairo_stroke_preserve(cr);
	//cairo_stroke(cr);

	cairo_set_source_rgb(cr, 0.3, 0.4, 0.6);
	//cairo_fill (cr);

//	cerr<<"fname:"<<fname<<endl;
//	cerr<<"||||||||||||||||||||||||||||||||||||||||||"<<endl;
	//exit(1);
	cairo_surface_write_to_png(surface, fname);
	cairo_destroy(cr);
	cairo_surface_destroy(surface);
	return true;
}
